﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Linq;
using UTSDAL.LINQSQL.Model;
using UTSDAL.LINQSQL.Helper;

namespace UTSDAL.LINQSQL.DAO
{

    public class GenericDAO<E, K> where E : class
    {
        private UTSDataContext context = DataContextHelper.Context;
        
        public UTSDataContext Context
        {
            get { return context; }
            set { context = value; }
        }


        public virtual void save(E instance)
        {

            this.save();
        }

        public virtual void save()
        {
            context.SubmitChanges();
        }


        public virtual List<E> selectAll()
        {
            return context.GetTable<E>().ToList();
        }


        public virtual void insert(E instance)
        {
            context.GetTable<E>().InsertOnSubmit(instance);
            context.SubmitChanges();
        }


        public virtual E insertAndReturn(E instance)
        {
            context.GetTable<E>().InsertOnSubmit(instance);
            context.SubmitChanges();

            return instance;
        }

        public virtual void remove(E instance)
        {
            context.GetTable<E>().DeleteOnSubmit(instance);
            context.SubmitChanges();
        }


        public String getKeyProperty()
        {
            String primaryKeyFieldName = typeof(E).Name + "Id";
            return primaryKeyFieldName;
        }


        public Expression<Func<E, bool>> getLambaKey(K id)
        {

            var parameter = Expression.Parameter(typeof(E), "e");
            var propId = Expression.Property(parameter, typeof(E).GetProperty(getKeyProperty()));

            return Expression.Lambda<Func<E, bool>>(Expression.Equal(propId, Expression.Constant(id)), parameter);
        }

        public virtual E findById(K id)
        {
            return context.GetTable<E>().SingleOrDefault(getLambaKey(id));
        }

        public virtual void deleteAll()
        {
            List<E> items = selectAll();
            context.GetTable<E>().DeleteAllOnSubmit(items);
            context.SubmitChanges();
        }
    }
}
